﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Newtonsoft.Json.Linq;
using BLL;

namespace WeChat.Common
{
    public class GetUsers
    {
        GetReturnJson gr = new GetReturnJson();
        string accesstoken = GetAccess_token.getAccesstoken();
        SubscribesBLL sb = new SubscribesBLL();
        string last_openid = "";//openid最后一个值
        int total = 0;//关注用户总数

        //获取关注用户信息并保存至数据库
        public string getUserInfo(string openid)
        {
            string url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accesstoken + "&openid=" + openid + "&lang=zh_CN";
            string rejson = gr.getReturnJson(url);
            //string rejson = "{\"subscribe\":1,\"openid\":\"aaaa\",\"nickname\":\"拼丶搏\",\"sex\":1,\"language\":\"zh_CN\",\"city\":\"深圳\",\"province\":\"广东\",\"country\":\"中国\",\"headimgurl\":\"http://wx.qlogo.cn/mmopen/ibhOzFI9ibk15G3a0avOEJ5tKJwGPbGoOufPBuO2K4nibg1DApL7m3kBCwZxGFBxtibnm5e7BbaN2pokE0YyX6S1Fg/0\",\"subscribe_time\":1451360118,\"remark\":\"\",\"groupid\":0}";
            JObject jo = JObject.Parse(rejson);
            if (rejson.Contains("errcode"))
            {
                return "请求用户信息失败，errcode：" + jo["errcode"].ToString();
            }
            else
            {
                string unionid = "";
                if (rejson.Contains("unionid"))//只有在用户将公众号绑定到微信开放平台帐号后，才会出现该字段
                {
                    unionid = jo["unionid"].ToString();
                }
                string subscribe = jo["subscribe"].ToString();
                //string openid = jo["openid"].ToString();
                string nickname = jo["nickname"].ToString();
                string sex = jo["sex"].ToString();
                switch (sex)
                {
                    case "0":
                        sex = "未知";
                        break;
                    case "1":
                        sex = "男";
                        break;
                    case "2":
                        sex = "女";
                        break;
                }
                string language = jo["language"].ToString();
                string city = jo["city"].ToString();
                string province = jo["province"].ToString();
                string country = jo["country"].ToString();
                string headimgurl = jo["headimgurl"].ToString();
                string subscribe_time = jo["subscribe_time"].ToString();
                //string unionid = jo["unionid"].ToString();
                string remark = jo["remark"].ToString();
                string groupid = jo["groupid"].ToString();

                bool o = sb.addSubsUser(subscribe, openid, nickname, sex, language, city, province, country, headimgurl, subscribe_time, unionid, remark, groupid);
                if (o)
                {
                    return "保存用户信息成功";
                }
                else
                {
                    return "保存用户信息至数据库失败";
                }
            }

        }

        //批量获取关注用户openid。以此发送请求获取关注用户信息。一次最多拉取1W个用户openid。
        //若有更高需求再设计代码提高更新关注用户数量
        public string getOpenids()
        {
            string url = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + accesstoken;
            string rejson = gr.getReturnJson(url);
            if (rejson.Contains("errcode"))
            {
                ApplicationLog.Write("同步关注用户失败！返回json：" + rejson);
            }
            else
            {
                JObject jo = JObject.Parse(rejson);
                total = Int32.Parse(jo["total"].ToString());//关注用户总数，后期可更新接口，根据此值来设计算法同步所有数据

                last_openid = jo["next_openid"].ToString();
            }
            return rejson;
        }

        /// <summary>
        /// 同步关注用户信息批量插入到数据库
        /// 一次最多执行100个，超过100个则执行循环体
        /// </summary>
        public void synchroUsers()
        {
            string url = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=" + accesstoken;
            int index = 0;
            string json = getOpenids();//得到用户openid列表
            if (!json.Contains("errcode"))
            {
                //新建json类，将得到的openid组装成新json格式来请求用户信息
                JObject jc = new JObject();
                JArray jr = new JArray();
                jc.Add("user_list", jr);

                JObject jo = JObject.Parse(json);
                JArray ja = JArray.Parse(jo["data"]["openid"].ToString());
                if (total > 100)
                {
                    for (int i = 0; i <= total / 100; i++)
                    {
                        int j = 0;
                        for (j = index; j < index + 100; j++)//每100个循环结束，凑成新json插入数据库
                        {
                            JToken jt = ja[j];
                            string openid = jt.ToString();
                            jr.Add(new JObject(new JProperty("openid", openid), new JProperty("lang", "zh-CN")));
                            if (j == total) break;
                        }
                        index = j;
                        BulkInsert(url, jc.ToString());//批量插入数据库
                    }
                }
                else
                {
                    foreach (JToken jt in ja)
                    {
                        string openid = jt.ToString();
                        jr.Add(new JObject(new JProperty("openid", openid), new JProperty("lang", "zh-CN")));
                    }
                    BulkInsert(url, jc.ToString());//批量插入数据库
                }
            }

        }

        //发送请求得到用户信息列表批量插入数据库
        private void BulkInsert(string url, string json)
        {
            DataTable dt = createUsersDt();
            string rejson = gr.postReturnJson(url, json);
            JObject jo = JObject.Parse(rejson);
            JArray ja = JArray.Parse(jo["user_info_list"].ToString());
            foreach (JToken jt in ja)
            {
                int subscribe = Int32.Parse(jt["subscribe"].ToString());
                string openid = jt["openid"].ToString();
                string nickname = jt["nickname"].ToString();
                string sex = jt["sex"].ToString();
                switch (sex)
                {
                    case "0":
                        sex = "未知";
                        break;
                    case "1":
                        sex = "男";
                        break;
                    case "2":
                        sex = "女";
                        break;
                }
                string language = jt["language"].ToString();
                string city = jt["city"].ToString();
                string province = jt["province"].ToString();
                string country = jt["country"].ToString();
                string headimgurl = jt["headimgurl"].ToString();
                string subscribe_time = FormatTimeBLL.formatTime(jt["subscribe_time"].ToString());
                string unionid = "";
                if (rejson.Contains("unionid"))//只有在用户将公众号绑定到微信开放平台帐号后，才会出现该字段
                {
                    unionid = jt["unionid"].ToString();
                }
                string remark = jt["remark"].ToString();
                int groupid = Int32.Parse(jt["groupid"].ToString());
                dt.Rows.Add((new object[] { null, subscribe, openid, nickname, sex, language, city, province, country, headimgurl, subscribe_time, unionid, remark, groupid }));
            }
            sb.synchroSubUsers("subscribes", dt);
        }

        //新建一个和用户信息表subscribes表结构一样的datatable，并插入数据批量保存
        private DataTable createUsersDt()
        {
            DataTable dt = new DataTable();
            DataColumn dc = dt.Columns.Add("id", Type.GetType("System.Int32"));
            dc.AutoIncrement = true;//自动增加
            dc.AutoIncrementSeed = 1;//起始为1
            dc.AutoIncrementStep = 1;//步长为1
            dc.AllowDBNull = false;
            //subscribe,openid, nickname, sex, language, city, province, country, headimgurl,subscribe_time, unionid, remark, groupid
            dt.Columns.Add("subscribe", Type.GetType("System.Int32"));
            dt.Columns.Add("openid", Type.GetType("System.String"));
            dt.Columns.Add("nickname", Type.GetType("System.String"));
            dt.Columns.Add("sex", Type.GetType("System.String"));
            dt.Columns.Add("language", Type.GetType("System.String"));
            dt.Columns.Add("city", Type.GetType("System.String"));
            dt.Columns.Add("province", Type.GetType("System.String"));
            dt.Columns.Add("country", Type.GetType("System.String"));
            dt.Columns.Add("headimgurl", Type.GetType("System.String"));
            dt.Columns.Add("subscribe_time", Type.GetType("System.DateTime"));
            dt.Columns.Add("unionid", Type.GetType("System.String"));
            dt.Columns.Add("remark", Type.GetType("System.String"));
            dt.Columns.Add("groupid", Type.GetType("System.Int32"));
            return dt;
        }
    }
}
